﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace TD.TheGame
{
    abstract class Level
    {
        public List<EnemySprite> Enemys
        {
            get;
            set;
        }

        protected Game game;
        protected int width;
        protected int heigt;
        protected Random random;

        private int startingChance;
        private int currentTime;
        private int maxTime;
        protected int yDifference;

        private int currentEnemy;

        public LevelState LvlState
        {
            get;
            set;
        }

        public Level(Game g)
        {
            yDifference = 15;
            game = g;
            width = g.Window.ClientBounds.Width;
            heigt = g.Window.ClientBounds.Height;
            random = new Random();
            Enemys = new List<EnemySprite>();
            maxTime = 500; //2000
            //Reset();
            LvlState = LevelState.GameOver;
        }

        public void Initialize()
        {
            addToList();
            Shuffle(Enemys);
        }

        //public void Reset()
        //{
        //    startingChance = 20;
        //    currentEnemy = 0;

        //    //reset position and state foreach sprite
        //    int yDifference = 10;
            
        //    foreach (EnemySprite enemy in Enemys)
        //    {
        //        enemy.State = SpriteEnumState.Normal;
        //        enemy.Position = new Vector2(width, heigt - 100 - random.Next(0, 10) * yDifference);
        //    }

        //    LvlState = LevelState.Waiting;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// 
        abstract public void addToList();

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        public virtual void Update(GameTime gameTime)
        {
            foreach (var enemy in Enemys)
            {
                enemy.Update(gameTime);
            }
            //Spawn Enemy 
            spawnEnemey(gameTime);
            //Check if game is finished
            if (checkIfFinished())
            {
                LvlState = LevelState.GameOver;
                OpenShop();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="gameTime"></param>
        public virtual void Draw(GameTime gameTime)
        {
            foreach (var enemy in Enemys)
            {
                enemy.Draw(gameTime);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        protected bool checkIfFinished()
        {
            //if no sprite is normal, lvl is finished
            bool check = true;
            foreach (var enemy in Enemys)
            {
                if (enemy.State == SpriteEnumState.Normal || enemy.State == SpriteEnumState.Shoot)
                {
                    return false;
                }
                if (enemy.State == SpriteEnumState.Die && enemy.endSprite == false)
                {
                    return false;
                }
            }
            return check;
        }

        protected void spawnEnemey(GameTime gameTime)
        {
            if (currentEnemy < Enemys.Count())
            {
                // increment startingChance after an amount of time 
                currentTime += gameTime.ElapsedGameTime.Milliseconds;
                if (currentTime > maxTime)
                {
                    currentTime = 0;
                    startingChance += 5;
                    if (startingChance > 70)
                    {
                        startingChance = 70;
                    }
                    int randomNr = random.Next(0, 100);
                    if (randomNr <= startingChance)
                    {
                        Enemys[currentEnemy].Active = true;
                        currentEnemy++;
                    }
                }
            }
        }

        protected static void Shuffle(List<EnemySprite> list)
        {
            Random rng = new Random();
            int n = list.Count;
            while (n > 1)
            {
                n--;
                int k = rng.Next(n + 1);
                EnemySprite value = list[k];
                list[k] = list[n];
                list[n] = value;
            }
        }

        /**
         * The following event lets us open the shop when a level is over.
         */
        public event FinishedLevel OnFinishedLevel;
        protected virtual void OpenShop()
        {
            if (OnFinishedLevel != null)
            {
                OnFinishedLevel(this);
            }
        }
    }

    internal delegate void FinishedLevel(Level level);
}
